package cn.edik.plugin.dubbo.core;

import cn.edik.plugin.dubbo.annotation.Service;
import com.jfinal.aop.Enhancer;
import com.jfinal.kit.StrKit;
import org.apache.dubbo.config.*;

import java.util.Map;

public class DubboConfigFactory {

    private ApplicationConfig applicationConfig = new ApplicationConfig();

    private RegistryConfig registryConfig = new RegistryConfig();

    private ProtocolConfig protocolConfig = new ProtocolConfig();

    private ProviderConfig providerConfig = new ProviderConfig();

    private ConsumerConfig consumerConfig = new ConsumerConfig();

    public DubboConfigFactory(String applicationName, String registryAddress, String protocolName) {
        applicationConfig.setName(applicationName);
        registryConfig.setAddress(registryAddress);
        protocolConfig.setName(protocolName);
        consumerConfig.setApplication(applicationConfig);
        providerConfig.setApplication(applicationConfig);
    }

    @SuppressWarnings("unchecked")
    public <T> ServiceConfig<T> createServiceConfig(Class<?> cl, Service service, Class<?> in) throws InstantiationException, IllegalAccessException {
        ServiceConfig<T> serviceConfig = new ServiceConfig<T>();
        serviceConfig.setApplication(applicationConfig);
        serviceConfig.setRegistry(registryConfig);
        serviceConfig.setProtocol(protocolConfig);
        serviceConfig.setInterface(in);
//        serviceConfig.setRef(service);
        serviceConfig.setProvider(providerConfig);

        if (service.needEnhancer()) {
            serviceConfig.setRef((T) Enhancer.enhance(cl));
        } else {
            serviceConfig.setRef((T) cl.newInstance());
        }
        if (StrKit.notBlank(service.token())) {
            serviceConfig.setToken(service.token());
        }
        if (StrKit.notBlank(service.stub())) {
            serviceConfig.setStub(service.stub());
        }
        if (StrKit.notBlank(service.mock())) {
            serviceConfig.setMock(service.mock());
        }
        if (StrKit.notBlank(service.accesslog())) {
            serviceConfig.setAccesslog(service.accesslog());
        }
        if (StrKit.notBlank(service.document())) {
            serviceConfig.setDocument(service.document());
        }
        if (StrKit.notBlank(service.filter())) {
            serviceConfig.setFilter(service.filter());
        }
        if (StrKit.notBlank(service.layer())) {
            serviceConfig.setFilter(service.filter());
        }
        if (StrKit.notBlank(service.listener())) {
            serviceConfig.setListener(service.listener());
        }
        if (StrKit.notBlank(service.owner())) {
            serviceConfig.setOwner(service.owner());
        }
        if (StrKit.notBlank(service.path())) {
            serviceConfig.setPath(service.path());
        }
        if (StrKit.notBlank(service.proxy())) {
            serviceConfig.setProxy(service.proxy());
        }
        if (StrKit.notBlank(service.version())) {
            serviceConfig.setVersion(service.version());
        }
        if (StrKit.notBlank(service.group())) {
            serviceConfig.setGroup(service.group());
        }
        serviceConfig.setCluster(service.cluster().toString().toLowerCase());
        serviceConfig.setLoadbalance(service.loadbalance().toString().toLowerCase());
        serviceConfig.setTimeout(service.timeout());
        serviceConfig.setExecutes(service.executes());
        serviceConfig.setDynamic(service.dynamic());
        serviceConfig.setDeprecated(service.deprecated());
        serviceConfig.setDelay(service.delay());
        serviceConfig.setConnections(service.connections());
        serviceConfig.setAsync(service.async());
        serviceConfig.setActives(service.actives());
        serviceConfig.setWeight(service.weight());
        serviceConfig.setRegister(service.register());
        serviceConfig.setRetries(service.retries());
        return serviceConfig;
    }


    public <T> ReferenceConfig<T> createReferenceConfig(Class<?> interfaceClass, Map<String, String> config) {
        ReferenceConfig<T> referenceConfig = new ReferenceConfig<T>();
        referenceConfig.setApplication(applicationConfig);
        referenceConfig.setRegistry(registryConfig);
        referenceConfig.setConsumer(consumerConfig);
        referenceConfig.setInterface(interfaceClass);
        if (StrKit.notBlank(config.get("interfaceName"))) {
            referenceConfig.setInterface(config.get("interfaceName"));
        }
        if (StrKit.notBlank(config.get("group"))) {
            referenceConfig.setGroup(config.get("group"));
        }
        if (StrKit.notBlank(config.get("version"))) {
            referenceConfig.setVersion(config.get("version"));
        }
        if (StrKit.notBlank(config.get("cache"))) {
            referenceConfig.setCache(config.get("cache"));
        }
        if (StrKit.notBlank(config.get("check"))) {
            referenceConfig.setCheck(Boolean.valueOf(config.get("check")));
        }
        if (StrKit.notBlank(config.get("retries"))) {
            referenceConfig.setRetries(Integer.valueOf(config.get("retries")));
        }
        if (StrKit.notBlank(config.get("cluster"))) {
            referenceConfig.setCluster(config.get("cluster"));
        }
        if (StrKit.notBlank(config.get("stub"))) {
            referenceConfig.setStub(config.get("stub"));
        }
        if (StrKit.notBlank(config.get("mock"))) {
            referenceConfig.setMock(config.get("mock"));
        }
        if (StrKit.notBlank(config.get("loadbalance"))) {
            referenceConfig.setLoadbalance(config.get("loadbalance"));
        }
        if (StrKit.notBlank(config.get("timeout"))) {
            referenceConfig.setTimeout(Integer.valueOf(config.get("timeout")));
        }
        if (StrKit.notBlank(config.get("connections"))) {
            referenceConfig.setConnections(Integer.valueOf(config.get("connections")));
        }
        if (StrKit.notBlank(config.get("async"))) {
            referenceConfig.setAsync(Boolean.valueOf(config.get("async")));
        }
        if (StrKit.notBlank(config.get("generic"))) {
            referenceConfig.setGeneric(config.get("generic"));
        }
        if (StrKit.notBlank(config.get("url"))) {
            referenceConfig.setUrl(config.get("url"));
        }
        if (StrKit.notBlank(config.get("validation"))) {
            referenceConfig.setValidation(config.get("validation"));
        }
        if (StrKit.notBlank(config.get("proxy"))) {
            referenceConfig.setProxy(config.get("proxy"));
        }
        if (StrKit.notBlank(config.get("client"))) {
            referenceConfig.setClient(config.get("client"));
        }
        if (StrKit.notBlank(config.get("owner"))) {
            referenceConfig.setOwner(config.get("owner"));
        }
        if (StrKit.notBlank(config.get("actives"))) {
            referenceConfig.setActives(Integer.valueOf(config.get("actives")));
        }
        if (StrKit.notBlank(config.get("filter"))) {
            referenceConfig.setFilter(config.get("filter"));
        }
        if (StrKit.notBlank(config.get("listener"))) {
            referenceConfig.setListener(config.get("listener"));
        }
        if (StrKit.notBlank(config.get("layer"))) {
            referenceConfig.setLayer(config.get("layer"));
        }
        if (StrKit.notBlank(config.get("init"))) {
            referenceConfig.setInit(Boolean.valueOf(config.get("init")));
        }
        if (StrKit.notBlank(config.get("protocol"))) {
            referenceConfig.setProtocol(config.get("protocol"));
        }
        return referenceConfig;
    }

    public void setApplicationVersionSafety(String applicationVersion) {
        if (StrKit.notBlank(applicationVersion)) {
            applicationConfig.setVersion(applicationVersion);
        }
    }

    public void setApplicationQosPort(Integer qosPort) {
        if (null != qosPort && qosPort > 2000) {
            applicationConfig.setQosPort(qosPort);
        }
    }

    public void setRegistryUsernameSafety(String registryUsername) {
        if (StrKit.notBlank(registryUsername)) {
            registryConfig.setUsername(registryUsername);
        }
    }

    public void setRegistryPasswordSafety(String registryPassword) {
        if (StrKit.notBlank(registryPassword)) {
            registryConfig.setPassword(registryPassword);
        }
    }

    public void setProtocolPortSafety(Integer protocolPort) {
        if (protocolPort != null) {
            protocolConfig.setPort(protocolPort);
        }
    }

    public void setProtocolThreadsSafety(Integer protocolThreads) {
        if (protocolThreads != null) {
            protocolConfig.setThreads(protocolThreads);
        }
    }

    public void setProviderTokenSafety(String providerToken) {
        if (StrKit.notBlank(providerToken)) {
            providerConfig.setToken(providerToken);
        }
    }

    public ApplicationConfig getApplicationConfig() {
        return applicationConfig;
    }

    public RegistryConfig getRegistryConfig() {
        return registryConfig;
    }

    public ProtocolConfig getProtocolConfig() {
        return protocolConfig;
    }

    public ProviderConfig getProviderConfig() {
        return providerConfig;
    }
}
